package com.sf.rbac.web.interceptor;

import com.alibaba.fastjson.JSONObject;
import com.sf.rbac.anno.RequiredPermission;
import com.sf.rbac.cons.RedisConst;
import com.sf.rbac.domain.Employee;
import com.sf.rbac.util.JsonResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.Set;

@Component
public class CheckPermissionInterceptor extends HandlerInterceptorAdapter {
    @Autowired
    private StringRedisTemplate redisTemplate;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        response.setContentType("application/json;charset=utf8");
        // 1获取请求头中的userId
        String userId = request.getHeader("userId");
        // 2拼接redis key 获取用户信息的key
        String objJSon = redisTemplate.opsForValue().get(RedisConst.EMPLOYEE_INFO_PREFIX + userId);
        System.out.println(objJSon);
        // 3 把json 字符串转成 Employee
        Employee employee = JSONObject.parseObject(objJSon, Employee.class);
        // 4判断当前登录用户是否是超级管理员
        // 5 如果是超级近管理员放行
        if (employee.isAdmin()) {
            return true;
        }
        // 6 如果不是，先获取到当前访问的方法
        if (handler instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            Method method = handlerMethod.getMethod();
            // 7通过method.getAnnotion()获取方法头上的自定义注解
            RequiredPermission annotation = method.getAnnotation(RequiredPermission.class);
            //8 判断自定义注解是否为空
            // 9如果为空直接放行
            if (annotation == null) {
                return true;
            }
            //10 如果不为空，从注解中获取权限表达式
            String expression = annotation.expression();
            //11 上redis 当中获取用户所具备权限表达式集合Set
            String expressionObjJson = redisTemplate.opsForValue().get(RedisConst.EMPLOYEE_EXPRESSION_PREFIX + userId);
            Set set = JSONObject.parseObject(expressionObjJson, Set.class);
            // 12 判断expression是否在集合中
            //13 如果在集合中 表示它有这个权限 ，放行
            if (set.contains(expression)) {
                return true;
            }
            // 14 如果不在集合中{403，‘没有权限’,fail,null}
            response.getWriter().write(JSONObject.toJSONString(new JsonResult(403, "没有权限", "fail", null)));
            return false;
        }
        return false;
    }


}
